﻿#region licence
//  Copyright 2008 Michael Cromwell

//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at

//       http://www.apache.org/licenses/LICENSE-2.0

//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Boo.Lang.Compiler.Ast;

namespace log4net.altconf.Steps
{
    /// <summary>
    /// Used for syntatic sugar, the block in with_appenders call
    /// each line is morphed into a argument list and passed to
    /// the <see cref="Log4NetDslConfiguration.UseAppenders"/> method.
    /// </summary>
    public class WithAppendersTransformer : DepthFirstTransformer
    {
        public override void OnMacroStatement(MacroStatement node)
        {
            if (node.Name.Equals("with_appenders"))
            {
                if (node.Arguments.Count > 0)
                    Boo.Lang.Compiler.CompilerErrorFactory.MacroExpansionError(node, new Exception("with_appenders should not be supplied arguments."));

                if (node.Block != null)
                {
                    var exprs = RetrieveExpressions(node.Block);
                    var mth = new MemberReferenceExpression();
                    mth.Name = "UseAppenders";
                    mth.Target = new SelfLiteralExpression(node.LexicalInfo);
                    var mie = new MethodInvocationExpression();
                    mie.LexicalInfo = node.LexicalInfo;
                    mie.Arguments = exprs;
                    mie.Target = mth;
                    node.ReplaceBy(new ExpressionStatement(mie));
                }
            }
            base.OnMacroStatement(node);
        }

        private static ExpressionCollection RetrieveExpressions(Block block)
        {
            var exprs = new ExpressionCollection();
            if (block.HasStatements)
            {
                foreach (var stmt in block.Statements)
                {
                    var macroStmt = stmt as MacroStatement;
                    var name = (macroStmt.Name.StartsWith("@")) ? macroStmt.Name.Substring(1) : macroStmt.Name;
                    exprs.Add(new StringLiteralExpression(macroStmt.LexicalInfo, name));
                }
            }
            return exprs;
        } 
    }
}
